﻿namespace Journey.Domain
{
    using System;

    /// <summary>
    /// 实体基类。
    /// </summary>
    public abstract class EntityBase : IEntity
    {
        /// <summary>
        /// 初始化实体基类。
        /// </summary>
        protected EntityBase()
            : this(Guid.Empty, DateTime.Now)
        {
        }

        /// <summary>
        /// 初始化实体基类。
        /// </summary>
        /// <param name="id">实体编号。</param>
        /// <param name="created">创建时间。</param>
        protected EntityBase(Guid id, DateTime created)
        {
            this.Id = id;
            this.Created = created;
        }

        /// <summary>
        /// 实体编号。
        /// </summary>
        public Guid Id { get; protected set; }

        /// <summary>
        /// 创建时间。
        /// </summary>
        public DateTime Created { get; set; }

        /// <summary>
        /// 表示该实体是否是临时的。
        /// </summary>
        /// <returns>临时的则返回 true，否则返回 false。</returns>
        public bool IsTransient()
        {
            return this.Id == Guid.Empty;
        }

        /// <summary>
        /// 改变当前实体编号。
        /// </summary>
        /// <param name="identity">实体编号。</param>
        public void ChangeCurrentIdentity(Guid identity)
        {
            if (!this.IsTransient())
                this.Id = identity;
        }

        #region Overrides Methods

        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (!(obj is EntityBase))
                return false;

            if (ReferenceEquals(this, obj))
                return true;

            var item = (EntityBase)obj;

            if (item.IsTransient() || IsTransient())
                return false;

            return item.Id == this.Id;
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return !IsTransient() ? this.Id.GetHashCode() ^ 31 : base.GetHashCode();
        }

        /// <summary>
        /// 重载“==”操作符
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static bool operator ==(EntityBase left, EntityBase right)
        {
            return Object.Equals(left, null) ? (Object.Equals(right, null)) : left.Equals(right);
        }

        /// <summary>
        /// 重载“!=”操作符
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static bool operator !=(EntityBase left, EntityBase right)
        {
            return !(left == right);
        }

        #endregion Overrides Methods
    }
}